package com.breeze.socketdemo.tcp;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import com.breeze.socketdemo.MainActivity;
import com.breeze.socketdemo.utils.MyUtil;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class TcpServer {
    private static final String TAG = "TcpServer";
    private static final int MSG_SEND = 0;
    public static final int PORT = 58627;
    private HandlerThread mSendThread;
    private Handler mSendHandler;
    private PrintWriter mPrintWriter;
    private boolean mRunning;
    private Handler mainHandler;

    public TcpServer(Handler handler) {
        mainHandler = handler;
    }

    public void start() {
        if (mRunning) {
            Log.i(TAG, "服务端已启动");
            return;
        }
        mRunning = true;
        new RunThread().start();
    }

    public void close() {
        mRunning = false;
    }

    public void sendMsg(final String msg) {
        Message.obtain(mSendHandler, MSG_SEND, msg).sendToTarget();
    }

    class RunThread extends Thread {
        @Override
        public void run() {
            super.run();
            List<Socket> peers = new ArrayList<>();
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(PORT);
                while (mRunning) {
                    Log.i(TAG, "accept...");
                    final Socket client = serverSocket.accept();
                    Log.i(TAG, "accept one client=" + client);
                    peers.add(client);
                    new ReceiveThread(client).start();
                    mSendThread = new HandlerThread("client_send");
                    mSendThread.start();
                    mSendHandler = new Handler(mSendThread.getLooper(), new TcpServer.SendMessageCallback());
                    mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())));
                }

            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, "accept has exception " + e.getMessage());
                return;
            }
        }
    }

    class ReceiveThread extends Thread {
        private Socket client;

        public ReceiveThread(Socket client) {
            this.client = client;
        }

        @Override
        public void run() {
            super.run();
            if (client == null) {
                return;
            }
            BufferedReader br = null;
            try {
                br = new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8"));
                while (mRunning) {
                    String msg = br.readLine();
                    Log.i(TAG, "receive from client message:" + msg);
                    // 客户端断开时会收到null消息
                    if (msg == null) {
                        break;
                    }
                    if (mainHandler != null) {
                        Message.obtain(mainHandler, MainActivity.MSG_RECEIVE_FROM_CLIENT, msg).sendToTarget();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                MyUtil.close(br, client);
            }
        }
    }

    class SendMessageCallback implements Handler.Callback {

        @Override
        public boolean handleMessage(@NonNull Message msg) {
            int what = msg.what;
            switch (what) {
                case MSG_SEND:
                    sendMessage((String) msg.obj);
                    break;
            }
            return false;
        }

        private void sendMessage(String msg) {
            mPrintWriter.println(msg);
            mPrintWriter.flush();
        }
    }
}
